package com.thememaker.lockstyle;

import com.thememake.Constants;
import com.thememake.entity.ThemeFileInfo;
import com.thememake.util.FileUtils;
import com.thememake.util.xml.XmlUtils;
import com.thememake.util.xml.fontcolor.ReadXmlUtils;
import com.thememaker.lockstyle.bean.action.LaunchPad;
import com.thememaker.lockstyle.bean.command.IntentCommand;
import com.thememaker.lockstyle.bean.ui.Button;
import com.thememaker.lockstyle.bean.ui.Image;
import com.thememaker.util.ErrorLogUtils;
import com.thememaker.util.ThemeChangeUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBException;
import javax.xml.transform.TransformerException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Consumer;

public class IntentCommandUtils {
    private static List<IntentCommand> intentCommandList = new ArrayList<>();
    private static List<IntentCommand> intentCommandOtherList = new ArrayList<>();
    private static List<IntentCommand> changeList = new ArrayList<>();
    public static void ReadXmlInentCommand(Path lockpath, String launchpadpath, String qikupath) {
        intentCommandList = new ArrayList<>();
        Path path = Paths.get(lockpath + File.separator + "manifest.xml");
        File file = new File(lockpath + File.separator + "manifest.xml");
        System.err.println(qikupath);
        Document document = ReadXmlUtils.loadXml(path.toString());
        Element rootElement = document.getDocumentElement();
        NodeList nodeList = rootElement.getElementsByTagName("IntentCommand");

        Path qiku_path = Paths.get(qikupath + File.separator + "launchpad.xml");
        NodeList nodeListqiku = getNodelist(qiku_path);

        Path laupath = Paths.get(launchpadpath + File.separator + "launchpad.xml");
        NodeList nodeListlau = getNodelist(laupath);

        Map<String,LaunchPad> otherList = XmlToMap(nodeListqiku);
        Map<String,String> indexs = new HashMap<>();
        List<Element> eleList = new ArrayList<>();
        if (nodeList.getLength() != 0) {
            IntentCommand intentCommand;
            Map<String,String> intentCommandMap = new HashMap<>();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element element = (Element) nodeList.item(i);
                try {
                    intentCommand = (IntentCommand) XmlUtils.xml2java(IntentCommand.class, nodeList.item(i));
                    intentCommandMap.forEach((s,item)->System.out.println(s));
                    LaunchPad launchPad1 = XmlcheckCom(intentCommand, nodeListlau);
                    /*System.out.println(launchPad1.toString());*/
                    if (launchPad1.getIntentCommand().getIndex() == null) {
                        launchPad1 = XmlcheckCom(intentCommand, nodeListqiku);
                    } else {
                        launchPad1 = XmlcheckCom(intentCommand, nodeListlau);
                    }
                    intentCommand.setIndex(Optional.ofNullable(launchPad1.getIntentCommand().getIndex()).orElse(null));
                    if(intentCommandMap.get(intentCommand.getIndex()) == null) {
                        if (otherList.get(intentCommand.getIndex()) != null) {
                            if (indexs.get(intentCommand.getIndex()) == null) {
                                System.out.println("需要修改===》" + intentCommand.toString());
                                indexs.put(intentCommand.getIndex(), intentCommand.getIndex());
                                change(document, element, intentCommand, otherList);
                                intentCommandMap.put(intentCommand.getIndex(), "true");
                            }
                            eleList.add(element);
                        } else {
                            System.out.println("找不到===》" + intentCommand.toString());
                            try {
                                element.appendChild(document.createComment("此处快捷无法修改，请更换"));
                            }catch (Exception e){
                                e.printStackTrace();
                            }

                            intentCommandList.add(intentCommand);
                        }
                    }
                    /*if(!type) {
                        if(checkCom(intentCommand,nodeListqiku,document,true,element)!=null){
                            intentCommandList.add(checkCom(intentCommand,nodeListqiku,document,false,element));
                        }
                    }*/
                } catch (JAXBException e) {
                    e.printStackTrace();
                }
            }
            removeAttr(eleList);
        }
        try {
            new ReadXmlUtils().saveXml(document, file);
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    public static Boolean checkIntent(File file, ThemeFileInfo themeFileInfo, String typePath){
        intentCommandList = new ArrayList<>();
        intentCommandOtherList = new ArrayList<>();
        String qikupath = String.valueOf(FileUtils.getResFileOfThemeModel(typePath, "launchpad"));
        String lockpath = String.valueOf(Paths.get(themeFileInfo.getThemeDir().getPath(), themeFileInfo.getThemeType(), ThemeFileInfo.LOCKSTYLE_NAME, ThemeFileInfo.LOCKSCREEN_NAME));
        String launchpadpath = String.valueOf(Paths.get(themeFileInfo.getResModelFile("launchpad").getPath()));
        Path path = Paths.get(lockpath + File.separator + "manifest.xml");
        Document document = ReadXmlUtils.loadXml(path.toString());
        Element rootElement = document.getDocumentElement();
        NodeList nodeList = rootElement.getElementsByTagName("IntentCommand");

        Path qiku_path = Paths.get(qikupath + File.separator + "launchpad.xml");
        System.out.println(qikupath);
        NodeList nodeListqiku = getNodelist(qiku_path);

        Path laupath = Paths.get(launchpadpath + File.separator + "launchpad.xml");
        NodeList nodeListlau = getNodelist(laupath);
        Map<String,LaunchPad> otherList = XmlToMap(nodeListqiku);
        Map<String,IntentCommand> intentCommandMap = new HashMap<>();
        if (nodeList.getLength() != 0) {
            IntentCommand intentCommand;
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element element = (Element) nodeList.item(i);
                try {
                    intentCommand = (IntentCommand) XmlUtils.xml2java(IntentCommand.class, nodeList.item(i));
                    LaunchPad launchPad1 = XmlcheckCom(intentCommand, nodeListlau);
                    intentCommand.setIndex(Optional.ofNullable(launchPad1.getIntentCommand().getIndex()).orElse(null));
                    if(intentCommandMap.get(intentCommand.getIndex()) == null || intentCommandMap.get(intentCommand.getIndex()).equals(intentCommand)) {
                        if (otherList.get(intentCommand.getIndex()) == null) {
                            if (intentCommandMap.get(intentCommand.getIndex()) == null || intentCommandMap.get(intentCommand.getIndex()).equals(intentCommand)) {
                                Node node = element.getParentNode().getParentNode().getParentNode();
                                System.out.println("sab 层》》》》" + node.getNodeName());
                                Button btn = (Button) XmlUtils.xml2java(Button.class, node);
                                System.out.println(btn.getName());
                                intentCommand.setImage_name(btn.getName().replace("_btn", ".png").replace("_", "\\"));
                                intentCommandList.add(intentCommand);
                            }
                        } else {
                            Node node = element.getParentNode().getParentNode().getParentNode();
                            Button btn = (Button) XmlUtils.xml2java(Button.class, node);
                            intentCommand.setImage_name(btn.getName().replace("_btn", ".png").replace("_", "\\"));
                            intentCommandOtherList.add(intentCommand);
                            System.err.println(intentCommand.toString());
                        }
                        intentCommandMap.put(intentCommand.getIndex(), intentCommand);
                    }
                } catch (JAXBException e) {
                    e.printStackTrace();
                }
            }
            return intentCommandList.size() == 0;
        }
        return true;
    }

    private static void removeAttr(List<Element> eleList){
        eleList.forEach(item -> {
            try {
                if(item.getParentNode() != null){
                    item.getParentNode().removeChild(item);
                }
            }catch (Exception e){
                e.printStackTrace();
            }

        });
    }

    public static void deleIntent(File files, String btnName,String imgName){
        Path path = Paths.get(Paths.get(files.getPath()) + File.separator + "manifest.xml");
        File file = new File(Paths.get(files.getPath()) + File.separator + "manifest.xml");
        Document document = ReadXmlUtils.loadXml(path.toString());
        Element rootElement = document.getDocumentElement();
        NodeList nodeListBtn = rootElement.getElementsByTagName("Button");
        NodeList nodeListImg = rootElement.getElementsByTagName("Image");
        List<Element> eleList = new ArrayList<>();
        for (int i = 0; i < nodeListBtn.getLength(); i++) {
            Element element = (Element) nodeListBtn.item(i);
            try {
                Button btn = (Button) XmlUtils.xml2java(Button.class, nodeListBtn.item(i));
                if(btn.getName().equals(btnName)){
                    eleList.add(element);
                }
            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < nodeListImg.getLength(); i++) {
            Element element = (Element) nodeListImg.item(i);
            try {
                Image img = (Image) XmlUtils.xml2java(Image.class, nodeListImg.item(i));
                if(img.getSrc() != null){
                    if(Optional.ofNullable(img.getName()).orElse("error!").equals(imgName.replace(".png","").replace("\\","_"))){
                        eleList.add(element);
                    }
                }

            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        removeAttr(eleList);
        try {
            new ReadXmlUtils().saveXml(document, file);
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    public static Button getIntentBtn(File files,String name){
        Path path = Paths.get(Paths.get(files.getPath()) + File.separator + "manifest.xml");
        Document document = ReadXmlUtils.loadXml(path.toString());
        Element rootElement = document.getDocumentElement();
        NodeList nodeListBtn = rootElement.getElementsByTagName("Button");
        for (int i = 0; i < nodeListBtn.getLength(); i++) {
            try {
                Button btn = (Button) XmlUtils.xml2java(Button.class, nodeListBtn.item(i));
                if(btn.getName().equals(name)){
                    return btn;
                }

            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static void changeIntent(File files, String oldName, String newName, ThemeFileInfo themeFileInfo, String qikupath,Boolean doWhat){
        System.out.println(oldName+"----"+newName);
        String launchpadpath = String.valueOf(Paths.get(themeFileInfo.getResModelFile("launchpad").getPath()));

        Path path = Paths.get(Paths.get(files.getPath()) + File.separator + "manifest.xml");
        File file = new File(Paths.get(files.getPath()) + File.separator + "manifest.xml");
        Document document = ReadXmlUtils.loadXml(path.toString());
        Element rootElement = document.getDocumentElement();
        NodeList nodeList = rootElement.getElementsByTagName("IntentCommand");

        Path qiku_path = Paths.get(qikupath + File.separator + "launchpad.xml");
        NodeList nodeListqiku = getNodelist(qiku_path);

        Path laupath = Paths.get(launchpadpath + File.separator + "launchpad.xml");
        NodeList nodeListlau = getNodelist(laupath);
        Map<String,LaunchPad> otherList = XmlToMap(nodeListqiku);
        Map<String,String> intentCommandMap = new HashMap<>();
        IntentCommand intentCommand;
        List<Element> eleList = new ArrayList<>();
        Boolean type = true;
        for (int i = 0; i < nodeList.getLength(); i++) {
            Element element = (Element) nodeList.item(i);
            try {
                intentCommand = (IntentCommand) XmlUtils.xml2java(IntentCommand.class, nodeList.item(i));
                LaunchPad launchPad1 = XmlcheckCom(intentCommand, nodeListlau);
                intentCommand.setIndex(Optional.ofNullable(launchPad1.getIntentCommand().getIndex()).orElse(null));
                System.out.println(intentCommand.toString());
                if(intentCommand.getIndex() != null) {
                    if(intentCommand.getIndex().equals(oldName)){
                        if(doWhat){
                            intentCommand.setIndex(newName);
                            System.out.println("在这个地方改"+intentCommand.toString());
                            if(type){
                                change(document, element, intentCommand, otherList);
                                type = false;
                            }
                            intentCommandMap.put(newName, "true");
                        }
                        eleList.add(element);
                    }
                }

            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        removeAttr(eleList);
        try {
            new ReadXmlUtils().saveXml(document, file);
        } catch (TransformerException e) {
            e.printStackTrace();
        }

    }

    public static Map<String, LaunchPad> getChengeList(String qikupath){
        Path qiku_path = Paths.get(qikupath + File.separator + "launchpad.xml");
        NodeList nodeListqiku = getNodelist(qiku_path);
        return XmlToMap(nodeListqiku);
    }

    public static List<IntentCommand> getError(){
        return intentCommandList;
    }
    public static List<IntentCommand> getOther(){
        return intentCommandOtherList;
    }

    private static NodeList getNodelist(Path path){
        Document commondocumentlau = ReadXmlUtils.loadXml(path.toString());
        Element commonrootElementlau = commondocumentlau.getDocumentElement();
        return commonrootElementlau.getElementsByTagName("launchpad");
    }

    private static Map<String,LaunchPad> XmlToMap(NodeList nodeList){
        Map<String,LaunchPad> launchPadMap = new HashMap<>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            try {
                LaunchPad intentCommand = (LaunchPad) XmlUtils.xml2java(LaunchPad.class, nodeList.item(i));
                launchPadMap.put(intentCommand.getIndex(),intentCommand);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return launchPadMap;
    }

    private static LaunchPad XmlcheckCom(IntentCommand intentCommand,NodeList nodeListlau){
        try {
            for (int j = 0; j < nodeListlau.getLength(); j++) {
                LaunchPad launchPad = (LaunchPad) XmlUtils.xml2java(LaunchPad.class, nodeListlau.item(j));
                if (intentCommand.getClassString() != null) {
                    if (isContainsList(intentCommand.getAction(),launchPad.getLaunchPad_action()) && isContainsList(intentCommand.getClassString(),Optional.ofNullable(launchPad.getLaunchPad_class()).orElse(intentCommand.getClassString())) && isContainsList(intentCommand.getPackageString(),Optional.ofNullable(launchPad.getLaunchPad_package()).orElse(intentCommand.getPackageString()))) {
                        intentCommand.setIndex(launchPad.getIndex());
                    }
                }
                if (intentCommand.getType() != null) {
                    if (isContainsList(intentCommand.getAction(),launchPad.getLaunchPad_action()) && isContainsList(intentCommand.getCategory(),Optional.ofNullable(launchPad.getCategory()).orElse("defalt")) && isContainsList(intentCommand.getType(),Optional.ofNullable(launchPad.getType()).orElse("defalt"))) {
                        intentCommand.setIndex(launchPad.getIndex());
                    }
                }
                if (intentCommand.getType() == null && intentCommand.getClassString() == null) {
                    if (isContainsList(intentCommand.getAction(),launchPad.getLaunchPad_action())) {
                        intentCommand.setIndex(launchPad.getIndex());
                    }
                }
            }
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return new LaunchPad(intentCommand);
    }


    public static void change(Document document, Element element,IntentCommand lau,Map<String,LaunchPad> change){
        String[] strArray = change.get(lau.getIndex()).getLaunchPad_action().split(";");
        if(strArray.length>1){
            for(int i = 0;i<strArray.length;i++) {
                addAttr(lau, element,document, i,change);
            }
        }else{
            addAttr(lau,element,document,0,change);
        }
    }

    private static void addAttr(IntentCommand lau,Element element,Document document,int num,Map<String,LaunchPad> change){
        Element element1 = document.createElement("IntentCommand");
        element1.setAttribute("action", getLaunch(change.get(lau.getIndex()).getLaunchPad_action(),num));
        if(change.get(lau.getIndex()).getLaunchPad_class()!=null){
            element1.setAttribute("class", getLaunch(change.get(lau.getIndex()).getLaunchPad_class(),num));
        }
        if(change.get(lau.getIndex()).getLaunchPad_package()!=null){
            element1.setAttribute("package", getLaunch(change.get(lau.getIndex()).getLaunchPad_package(),num));
        }
        if(change.get(lau.getIndex()).getCategory()!=null){
            element1.setAttribute("category", getLaunch(change.get(lau.getIndex()).getCategory(),num));
        }
        if(change.get(lau.getIndex()).getType()!=null){
            element1.setAttribute("type", getLaunch(change.get(lau.getIndex()).getType(),num));
        }
        try {
            element.getParentNode().insertBefore(element1,element.getParentNode().getFirstChild());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private static String getLaunch(String text,int num){
        String[] strArray = text.split(";");
        return strArray[num];
    }


    public static void copyFile(File file,ThemeFileInfo themeFileInfo,Consumer<String> consumer){
        if(file == null){
            ErrorLogUtils.getInstance().createLog(themeFileInfo, "转换失败，未选择文件夹");
//            consumer.accept("");
        }else {
            intentCommandList = new ArrayList<>();
            String qikupath = String.valueOf(FileUtils.getResFileOfThemeModel(Constants.OS360, "launchpad"));
            String launchpadpath = String.valueOf(Paths.get(themeFileInfo.getResModelFile("launchpad").getPath()));
            try {
                ThemeChangeUtils.getInstance().editThemeXml(Paths.get(file.getPath()) + "/manifest.xml", Constants.OS360);
                IntentCommandUtils.ReadXmlInentCommand(Paths.get(file.getPath()), launchpadpath, qikupath);
                FileToZip.fileCopy(file.getPath()+"/manifest.xml", file.getPath()+ "/18_9_manifest.xml");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }


    public static boolean isContainsList(String text,String jurisdiction){
        boolean bResult = false;
        String[] strArray = jurisdiction.split(";");
        List<String > codeList = Arrays.asList(strArray);
        if(codeList.contains(text)){
            bResult = true;
        }
        return bResult;
    }
}
